import base64
import os
import uuid
import asyncio
import aiofiles
import aiohttp
import json
from fastapi import HTTPException
from config import Config
from utils import analyze_data, service, chat_history_manager, should_include_analysis, should_include_chart, TrendAnalyzer, LLMService
from models import UserRequest, UnitDateParams
import logging
from utils import convert_params
import time
from typing import Optional, Union, cast, List, Dict
from datetime import datetime, timedelta

logger = logging.getLogger(__name__)

async def process_sett_data(data: dict, debug: bool, user_query: str, params: dict, conversation_id: str, include_analysis: Optional[bool] = None, include_chart: Optional[bool] = None) -> dict:
    start_time = time.time()
    logging.info(f"[步骤6-轧差数据处理] 开始处理轧差数据")
    if data.get('respCode') != '00':
        logging.error(f"[API错误] 轧差查询失败: {data.get('respMsg')}")
        # 检查是否是权限错误
        error_msg = data.get('respMsg', '未知错误')
        if "权限" in error_msg or "没有权限" in error_msg or "无权" in error_msg:
            # 获取用户可以查询的单位列表
            try:
                from utils import get_user_available_units
                # 从params中获取手机号
                phone_number = params.get('phoneNo', '')
                if phone_number:
                    available_units = await get_user_available_units(phone_number)
                    if available_units:
                        raise HTTPException(status_code=403, detail=f"您没有权限查询此单位，请去统一对账平台进行绑定。您可以查询的单位有：{', '.join(available_units)}")
                    else:
                        # 无单位时返回空结果而不是错误
                        return {
                            "type": "sett_list",
                            "result": {
                                "answer": "您的微信手机号未绑定到任何清算单位或商户，请联系您的客户经理，完成绑定后可使用本清算智能体的功能。",
                                "conversation_id": conversation_id
                            },
                            "conversation_id": conversation_id,
                            "raw_data": None if not debug else {
                                "user_query": user_query,
                                "conversation_id": conversation_id,
                                "available_units": available_units
                            }
                        }
                else:
                    raise HTTPException(status_code=403, detail="您没有权限查询此单位，请去统一对账平台进行绑定。")
            except HTTPException:
                # 重新抛出HTTPException
                raise
            except Exception as e:
                logging.error(f"获取用户可用单位失败: {str(e)}")
                raise HTTPException(status_code=403, detail="您没有权限查询此单位，请去统一对账平台进行绑定。")
        else:
            raise HTTPException(status_code=400, detail=f"查询失败：{error_msg}")

    # 获取查询日期范围
    start_date = params.get('startDate')
    end_date = params.get('endDate')
    sett_list = data.get('settList', [])

    # 获取轧差表数据后，需要扩展查询时间范围来检测跨月记录
    # 因为API只返回完全在查询时间范围内的记录，所以需要扩展范围来获取可能跨月的记录
    extended_start_date = start_date
    extended_end_date = end_date
    
    # 如果查询的是单月数据，扩展到前后一个月以检测跨月记录
    try:
        start_date_obj = datetime.strptime(start_date, "%Y%m%d")
        end_date_obj = datetime.strptime(end_date, "%Y%m%d")
        
        # 如果查询范围在一个月内，扩展到前后一个月
        if start_date_obj.month == end_date_obj.month and start_date_obj.year == end_date_obj.year:
            # 扩展到前一个月的第一天和后一个月的最后一天
            if start_date_obj.month == 1:
                prev_month_start = datetime(start_date_obj.year-1, 12, 1)
            else:
                prev_month_start = datetime(start_date_obj.year, start_date_obj.month-1, 1)
                
            if end_date_obj.month == 12:
                next_month_end = datetime(end_date_obj.year+1, 1, 1)
                # 获取下个月的最后一天
                next_month_end = datetime(next_month_end.year, next_month_end.month+1, 1) - timedelta(days=1)
            else:
                next_month_end = datetime(end_date_obj.year, end_date_obj.month+2, 1) - timedelta(days=1)
            
            extended_start_date = prev_month_start.strftime("%Y%m%d")
            extended_end_date = next_month_end.strftime("%Y%m%d")
            
            logging.info(f"[跨月记录检测] 扩展查询时间范围: {extended_start_date} 至 {extended_end_date}")
    except Exception as e:
        logging.error(f"[跨月记录检测] 扩展时间范围失败: {str(e)}")
        # 如果扩展失败，使用原始时间范围
        extended_start_date = start_date
        extended_end_date = end_date
    
    # 只有在时间范围被扩展的情况下才重新查询API
    extended_sett_list = sett_list
    if extended_start_date != start_date or extended_end_date != end_date:
        try:
            # 使用扩展后的时间范围重新查询API以获取可能的跨月记录
            extended_params = params.copy()
            extended_params['startDate'] = extended_start_date
            extended_params['endDate'] = extended_end_date
            
            extended_data = await service.call_api(Config.SETT_API_PATH, extended_params)
            if isinstance(extended_data, dict):
                extended_sett_list = extended_data.get('settList', [])
                logging.info(f"[跨月记录检测] 扩展查询获取到{len(extended_sett_list)}条记录")
            else:
                logging.error(f"[跨月记录检测] 扩展查询API返回类型错误")
        except Exception as e:
            logging.error(f"[跨月记录检测] 扩展查询失败: {str(e)}")
    
    # 筛选查询时间段的记录
    # 使用轧差表本身的日期范围而不是确认日期进行筛选
    filtered_sett_list = []
    cross_month_sett_list = []  # 存储跨月的轧差表记录
    
    if start_date and end_date:
        # 首先筛选完全在查询时间范围内的记录
        # 只使用轧差表本身的日期范围进行筛选，不使用确认日期
        filtered_sett_list = [
            item for item in extended_sett_list
            if item.get('startDate', '') >= start_date and item.get('endDate', '') <= end_date
        ]
        
        # 然后找出跨月但与查询时间范围有交集的记录
        cross_month_sett_list = []
        for item in extended_sett_list:
            # 跳过已经在filtered_sett_list中的记录
            if item in filtered_sett_list:
                continue
                
            item_start = item.get('startDate', '')
            item_end = item.get('endDate', '')
            item_confirm = item.get('confirmDate', '')
            
            # 检查是否是跨月记录
            is_cross_month = False
            try:
                start_month = datetime.strptime(item_start, "%Y%m%d").month
                end_month = datetime.strptime(item_end, "%Y%m%d").month
                if start_month != end_month:
                    is_cross_month = True
            except:
                pass
            
            # 只有跨月记录才检查是否有交集
            if is_cross_month:
                # 检查是否有交集
                has_intersection = False
                if item_start and item_end:
                    # 检查时间段是否有交集
                    has_intersection = (
                        (item_start <= end_date and item_end >= start_date) or
                        (item_confirm and start_date <= item_confirm <= end_date)
                    )
                
                if has_intersection:
                    cross_month_sett_list.append(item)
    else:
        filtered_sett_list = extended_sett_list

    result_count = len(filtered_sett_list)
    cross_month_count = len(cross_month_sett_list)
    logging.info(f"[数据处理] 筛选后轧差记录数量: {result_count}条")
    logging.info(f"[数据处理] 跨月轧差记录数量: {cross_month_count}条")

    # 获取单位名称
    unit_name = "未知"
    try:
        # 从params中获取手机号和单位ID
        phone_number = params.get('phoneNo', '')
        unit_id = params.get('unitId', '')
        logging.info(f"[单位名称获取] 开始获取单位名称，手机号: {phone_number}, 单位ID: {unit_id}")
        
        if phone_number and unit_id:
            # 获取用户可查询单位列表
            from utils import get_user_available_units, safe_extract_unit_name
            available_units = await get_user_available_units(phone_number, return_full_info=True)
            logging.info(f"[单位名称获取] 获取到可查询单位数量: {len(available_units)}")
            
            # 查找匹配的单位名称
            for unit in available_units:
                if isinstance(unit, dict) and unit.get('unitId') == unit_id:
                    unit_name = safe_extract_unit_name(unit)
                    logging.info(f"[单位名称获取] 成功从单位列表中获取到单位名称: {unit_name}")
                    break
            else:
                logging.warning(f"[单位名称获取] 未在可查询单位列表中找到匹配的单位ID: {unit_id}")
                # 如果没有找到匹配的单位ID，使用第一个可查询单位作为备选
                if available_units and len(available_units) > 0:
                    first_unit = available_units[0]
                    if isinstance(first_unit, dict):
                        unit_name = safe_extract_unit_name(first_unit)
                        logging.info(f"[单位名称获取] 使用第一个可查询单位作为备选: {unit_name}")
                
                # 尝试从轧差数据中获取单位名称
                if unit_name == "未知" and filtered_sett_list and isinstance(filtered_sett_list[0], dict):
                    # 尝试从轧差数据中提取单位相关信息
                    company_id = filtered_sett_list[0].get('companyId')
                    if company_id:
                        # 关键修复：检查API返回数据与查询参数是否一致
                        if company_id != unit_id:
                            logging.warning(f"[单位名称获取] API返回数据与查询参数不匹配！查询unitId: {unit_id}, API返回companyId: {company_id}")
                            # 优先使用用户选择的单位名称，而不是API返回的单位
                            # 尝试从可用单位列表中查找用户选择的单位名称
                            for unit in available_units:
                                if isinstance(unit, dict) and unit.get('unitId') == unit_id:
                                    unit_name = safe_extract_unit_name(unit)
                                    logging.info(f"[单位名称获取] 使用用户选择的单位名称: {unit_name}")
                                    break
                            else:
                                # 如果找不到用户选择的单位，使用API返回的单位ID
                                unit_name = f"统一结算单位号: {company_id}"
                                logging.info(f"[单位名称获取] 从轧差数据中获取到单位信息: {unit_name}")
                        else:
                            unit_name = f"统一结算单位号: {company_id}"
                            logging.info(f"[单位名称获取] 从轧差数据中获取到单位信息: {unit_name}")
        else:
            logging.warning(f"[单位名称获取] 缺少必要参数，手机号: {phone_number}, 单位ID: {unit_id}")
            # 如果缺少参数，尝试获取第一个可查询单位作为备选
            if phone_number:
                try:
                    from utils import get_user_available_units, safe_extract_unit_name
                    available_units = await get_user_available_units(phone_number, return_full_info=True)
                    if available_units and len(available_units) > 0:
                        first_unit = available_units[0]
                        if isinstance(first_unit, dict):
                            unit_name = safe_extract_unit_name(first_unit)
                            logging.info(f"[单位名称获取] 缺少参数，使用第一个可查询单位作为备选: {unit_name}")
                except Exception as e:
                    logging.error(f"[单位名称获取] 获取备选单位名称失败: {str(e)}")
    except Exception as e:
        logging.error(f"获取单位名称失败: {str(e)}")
        unit_name = "未知"

    # 确保临时目录存在
    temp_dir = Config.TEMP_DOWNLOAD_PATH
    os.makedirs(temp_dir, exist_ok=True)

    # 构建竖向Markdown表格格式的结果和下载链接列表
    # 确定实际查询的时间范围（可能是扩展后的）
    actual_start_date = extended_start_date if extended_start_date != start_date else start_date
    actual_end_date = extended_end_date if extended_end_date != end_date else end_date
    
    if result_count == 0 and cross_month_count == 0:
        # 构建原始未找到记录的响应
        response = {
            "user_query": user_query,
            "summary": f"### 未找到符合条件的轧差表记录",
            "records": [],
            "download_links": []
        }
        
        # 尝试扩展查询，查找最近有数据的时间
        try:
            from utils_1 import enhance_no_data_response
            enhanced_response = await enhance_no_data_response(
                response,  # 原始响应
                params,    # 查询参数
                Config.SETT_API_PATH,  # API路径
                "sett",    # 查询类型
                service,   # 服务模块
                user_query # 用户查询
            )
            
            if enhanced_response:
                # 如果扩展查询找到了数据，返回增强的响应
                if debug:
                    enhanced_response["debug_info"] = {
                        "generated_params": params,
                        "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.SETT_API_PATH}",
                        "raw_response": data
                    }
                
                end_time = time.time()
                logging.info(f"[步骤6-轧差数据处理] 处理轧差数据耗时: {end_time - start_time:.2f}秒")
                return enhanced_response
        except Exception as e:
            logging.error(f"[扩展查询] 轧差表扩展查询失败: {str(e)}")
        
        # 如果扩展查询也失败或未找到数据，返回原始未找到记录的消息
        if debug:
            response["debug_info"] = {
                "generated_params": params,
                "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.SETT_API_PATH}",
                "raw_response": data
            }
        
        end_time = time.time()
        logging.info(f"[步骤6-轧差数据处理] 处理轧差数据耗时: {end_time - start_time:.2f}秒")
        return response
    elif result_count == 0 and cross_month_count > 0:
        # 只有跨月记录的情况
        result_lines = [f"### 查询完成，在指定时间范围（{start_date}至{end_date}）内未找到轧差表记录，但发现{cross_month_count}条跨月记录可能相关："]
        result_lines.append("\n跨月记录列表：")
        
        # 构建跨月记录的简要信息
        for idx, sett in enumerate(cross_month_sett_list, 1):
            tb_no = sett.get('tbNo', '未知')
            sett_start_date = sett.get('startDate', '未知')
            sett_end_date = sett.get('endDate', '未知')
            result_lines.append(f"{idx}. 轧差表编号：{tb_no}，日期范围：{sett_start_date}至{sett_end_date}")
        
        result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
        
        # 为跨月记录添加单位名称信息
        cross_month_records_with_unit = []
        for sett in cross_month_sett_list:
            # 创建记录副本并添加单位名称
            sett_copy = sett.copy()
            sett_copy['unit_name'] = unit_name  # 添加单位名称字段
            cross_month_records_with_unit.append(sett_copy)
        
        # 构建响应对象，包含跨月记录信息
        response = {
            "user_query": user_query,
            "summary": "\n".join(result_lines),
            "records": [],
            "download_links": [],
            "cross_month_records": cross_month_records_with_unit  # 添加跨月记录信息
        }
        
        # 将跨月记录信息添加到summary中，而不是添加新字段
        if debug:
            response["debug_info"] = {
                "generated_params": params,
                "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.SETT_API_PATH}",
                "raw_response": data
            }
        
        end_time = time.time()
        logging.info(f"[步骤6-轧差数据处理] 处理轧差数据耗时: {end_time - start_time:.2f}秒")
        return response
    elif result_count > 0 and cross_month_count > 0:
        # 既有正常记录又有跨月记录的情况
        result_lines = [f"### 查询成功，共找到{result_count}条轧差表记录（{start_date}至{end_date}），另外还有{cross_month_count}条跨月记录可能相关："]
        result_lines.append("\n#### 跨月记录列表：")
        
        # 构建跨月记录的简要信息
        for idx, sett in enumerate(cross_month_sett_list, 1):
            tb_no = sett.get('tbNo', '未知')
            sett_start_date = sett.get('startDate', '未知')
            sett_end_date = sett.get('endDate', '未知')
            result_lines.append(f"{idx}. 轧差表编号：{tb_no}，日期范围：{sett_start_date}至{sett_end_date}")
        
        result_lines.append("\n是否需要包含这些跨月记录？请回复'是'或'否'")
        
        # 先处理正常记录
        download_links = []
        records = []
        
        for idx, sett in enumerate(filtered_sett_list, 1):
            # 为每条记录生成下载链接
            file_id = str(uuid.uuid4())
            tb_no = sett.get('tbNo', '未知')
            file_name = f"{tb_no}.xls"
            download_url = f"{Config.API_BASE_URL}/download/{file_id}?filename={file_name}"

            # 构建单条记录的完整内容
            record_content = []
            record_content.append(f"#### 第{idx}条轧差表记录")
            record_content.append(f"| 序号 | {idx} |")
            record_content.append("|------|-----|")
            record_content.append(f"| 单位名称 | {unit_name} |")
            record_content.append(f"| 统一结算单位号 | {sett.get('companyId', '未知')} |")
            record_content.append(f"| 日期范围 | {sett.get('startDate', '未知')}至{sett.get('endDate', '未知')} |")
            record_content.append(f"| 消费笔数(笔) | {sett.get('totalTxnNum', '0')} |")
            record_content.append(f"| 合计消费金额(元) | {int(sett.get('totalTxnAmt', '0'))/100} |")
            record_content.append(f"| 实付金额(元) | {abs(int(sett.get('totalPayAmt', '0')))/100} |")
            record_content.append(f"| 消费手续费(元) | {int(sett.get('txnFeeAmt', '0'))/100} |")
            
            # 将完整记录内容作为单个字符串添加到records数组
            records.append("\n".join(record_content))

            # 添加到下载链接列表
            download_links.append({
                "index": idx,
                "tb_no": tb_no,
                "download_url": download_url,
                "file_name": file_name,
                "file_type": "xls"
            })
        
        # 为跨月记录添加单位名称信息
        cross_month_records_with_unit = []
        for sett in cross_month_sett_list:
            # 创建记录副本并添加单位名称
            sett_copy = sett.copy()
            sett_copy['unit_name'] = unit_name  # 添加单位名称字段
            cross_month_records_with_unit.append(sett_copy)
        
        # 构建响应对象，包含正常记录和跨月记录信息
        response = {
            "user_query": user_query,
            "summary": "\n".join(result_lines),
            "records": records,
            "download_links": download_links,
            "cross_month_records": cross_month_records_with_unit  # 添加跨月记录信息
        }
        
        # 将跨月记录信息添加到summary中，而不是添加新字段
        
        if debug:
            response["debug_info"] = {
                "generated_params": params,
                "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.SETT_API_PATH}",
                "raw_response": data
            }
        
        end_time = time.time()
        logging.info(f"[步骤6-轧差数据处理] 处理轧差数据耗时: {end_time - start_time:.2f}秒")
        return response
    # 智能判断是否需要数据分析和趋势图
    do_analysis = include_analysis if include_analysis is not None else should_include_analysis(user_query, "sett")
    do_chart = include_chart if include_chart is not None else should_include_chart(user_query, "sett")
    
    # 只有正常记录的情况
    # 如果没有跨月记录，使用原始查询时间范围；如果有跨月记录但用户选择不包含，也使用原始查询时间范围
    if cross_month_count == 0:
         # 没有跨月记录，使用原始查询时间范围
        result_lines = [f"### 查询成功，共找到{result_count}条轧差表记录（{start_date}至{end_date}）"]
    else:
        # 有跨月记录但用户选择不包含，使用原始查询时间范围
        result_lines = [f"### 查询成功，共找到{result_count}条轧差表记录（{start_date}至{end_date}）"]
    
    # 如果用户要求数据分析，则显示数据分析模式的提示信息
    if do_analysis or do_chart:
        result_lines = [f"### 数据分析结果"]
    
    # 创建独立的记录数组和下载链接列表
    records = []
    download_links = []

    for idx, sett in enumerate(filtered_sett_list, 1):
        # 为每条记录生成下载链接
        file_id = str(uuid.uuid4())
        tb_no = sett.get('tbNo', '未知')
        file_name = f"{tb_no}.xls"
        download_url = f"{Config.API_BASE_URL}/download/{file_id}?filename={file_name}"

        # 预生成文件
        try:
            # 调用下载接口
            logger.info(f"开始预生成文件: {file_name}")
            download_params = {
                "fileId": sett.get("fileId"),
                "unitId": sett.get("unitId"),
                "tbNo": tb_no
            }
            
            if not all(download_params.values()):
                logger.warning(f"记录缺少必要参数，跳过文件预生成: {tb_no}")
            else:
                # 调用下载API
                response = await service.call_api(Config.SETT_FILE_DOWN_API_PATH, download_params, stream=True)
                
                # 检查响应类型并进行类型断言
                if not hasattr(response, 'headers'):
                    logger.error(f"下载API返回类型错误，期望ClientResponse但得到: {type(response)}")
                    continue
                
                # 使用类型断言告诉类型检查器response的实际类型
                response = cast(aiohttp.ClientResponse, response)
                
                try:
                    # 添加类型检查，确保response是ClientResponse对象
                    if hasattr(response, 'headers') and response.headers.get("Content-Type") == "application/octet-stream":
                        # 保存文件到临时目录
                        file_path = os.path.join(temp_dir, f"{file_id}_{file_name}")
                        
                        # 异步保存文件内容（使用流式处理，避免大文件导致连接关闭）
                        if hasattr(response, 'content'):
                            async with aiofiles.open(file_path, 'wb') as f:
                                # 分块读取和写入数据，避免一次性读取大文件导致连接关闭
                                chunk_size = 65536  # 64KB
                                while True:
                                    try:
                                        chunk = await response.content.read(chunk_size)
                                        if not chunk:
                                            break
                                        await f.write(chunk)
                                    except Exception as e:
                                        logger.error(f"读取响应数据时发生错误: {str(e)}")
                                        break
                        
                        # 异步检查文件是否保存成功
                        if os.path.exists(file_path) and os.path.getsize(file_path) > 0:
                            logger.info(f"文件预生成成功: {file_path}")
                        else:
                            logger.error(f"文件预生成失败: {file_path}")
                    else:
                        # 处理非application/octet-stream类型的响应
                        content_type = response.headers.get("Content-Type", "unknown")
                        logger.warning(f"下载API返回非预期的Content-Type: {content_type}")
                        
                        # 尝试读取响应内容以便更好地诊断问题
                        response_content = None
                        try:
                            if hasattr(response, 'text'):
                                response_content = await response.text()
                                logger.error(f"下载API响应内容: {response_content[:500]}...")  # 只记录前500个字符
                            elif hasattr(response, 'json'):
                                error_data = await response.json()
                                logger.error(f"下载API错误响应: {error_data}")
                            else:
                                logger.error("下载API返回无法解析的响应格式")
                        except Exception as e:
                            logger.error(f"解析下载API响应失败: {str(e)}")
                        
                        # 记录HTTP状态码和响应头信息
                        status_code = getattr(response, 'status', 'unknown')
                        logger.error(f"下载API HTTP状态码: {status_code}")
                        logger.error(f"下载API响应头: {dict(response.headers) if hasattr(response, 'headers') else 'unavailable'}")
                finally:
                    # 确保关闭响应
                    if hasattr(response, 'closed') and hasattr(response, 'close') and not response.closed:
                        response.close()
        except Exception as e:
            logger.exception(f"文件预生成异常: {str(e)}")

        # 构建单条记录的完整内容
        record_content = []
        record_content.append(f"#### 第{idx}条轧差表记录")
        record_content.append(f"| 序号 | {idx} |")
        record_content.append("|------|-----|")
        record_content.append(f"| 单位名称 | {unit_name} |")
        record_content.append(f"| 统一结算单位号 | {sett.get('companyId', '未知')} |")
        record_content.append(f"| 日期范围 | {sett.get('startDate', '未知')}至{sett.get('endDate', '未知')} |")
        record_content.append(f"| 消费笔数(笔) | {sett.get('totalTxnNum', '0')} |")
        record_content.append(f"| 合计消费金额(元) | {int(sett.get('totalTxnAmt', '0'))/100} |")
        record_content.append(f"| 实付金额(元) | {abs(int(sett.get('totalPayAmt', '0')))/100} |")
        record_content.append(f"| 消费手续费(元) | {int(sett.get('txnFeeAmt', '0'))/100} |")
        

        
        # 将完整记录内容作为单个字符串添加到records数组
        records.append("\n".join(record_content))

        # 添加到下载链接列表
        download_links.append({
            "index": idx,
            "tb_no": tb_no,
            "download_url": download_url,
            "file_name": file_name,
            "file_type": "xls"
        })

    # 准备结果变量
    trend_data = None
    text_analysis = None
    
    # 根据判断结果决定是否执行数据分析和趋势图生成
    if do_analysis or do_chart:
        tasks = []
        
        if do_chart and filtered_sett_list:
            # 创建趋势图生成任务
            trend_task = asyncio.create_task(
                asyncio.to_thread(
                    TrendAnalyzer.generate_trend_chart,
                    data_list=filtered_sett_list,
                    date_field='startDate',
                    value_field='totalTxnAmt',
                    title=f'{unit_name}消费金额趋势分析',
                    x_label='日期',
                    y_label='金额(元)',
                    value_converter=lambda x: int(x)/100,
                    analysis_type="sett"
                )
            )
            tasks.append(('chart', trend_task))
        
        if do_analysis:
            # 创建文本数据分析任务
            analysis_task = asyncio.create_task(
                analyze_data(data, analysis_type="sett", start_date=start_date, end_date=end_date)
            )
            tasks.append(('analysis', analysis_task))
        
        # 等待所有任务完成
        if tasks:
            done, pending = await asyncio.wait([task for _, task in tasks], return_when=asyncio.ALL_COMPLETED)
            
            for task_type, task in tasks:
                if task in done:
                    try:
                        result = task.result()
                        if task_type == 'chart':
                            trend_data = result
                            logging.info(f"[趋势分析] 生成轧差金额趋势图成功")
                        elif task_type == 'analysis':
                            text_analysis = result
                    except Exception as e:
                        if task_type == 'chart':
                            logging.error(f"[趋势分析] 生成趋势图失败: {str(e)}")
                        elif task_type == 'analysis':
                            logging.error(f"[数据分析] 分析失败: {str(e)}")

    # 使用传入的conversation_id
    logging.info(f"[对话管理] 使用传入的conversation_id: {conversation_id}")

    # 构建响应对象
    response = {
        "user_query": user_query,
        "summary": result_lines[0] if result_lines else ("数据分析结果" if do_analysis or do_chart else ""),
        "records": records if not (do_analysis or do_chart) else [],  # 分开问时只返回查询数据
        "download_links": download_links if not (do_analysis or do_chart) else []  # 分开问时只返回下载链接
    }
    
    # 仅在用户没有要求分析或画图时返回趋势分析字段
    if not do_analysis and not do_chart:
        response["extend_question"] = "对数据进行趋势分析和可视化"
    
    # 只有在生成了分析结果时才包含analysis字段
    if text_analysis:
        response["analysis"] = text_analysis
    
    # 只有在生成了趋势图时才包含chart字段
    if trend_data and "trend_chart" in trend_data:
        response["chart"] = trend_data["trend_chart"]

    if debug:
        response["debug_info"] = {
            "generated_params": params,
            "target_api_url": f"{Config.TARGET_API_BASE_URL}{Config.SETT_API_PATH}",
            "raw_response": data
        }
    end_time = time.time()
    logging.info(f"[步骤6-轧差数据处理] 处理轧差数据耗时: {end_time - start_time:.2f}秒")
    return response

# 封装函数，类似Dify服务
async def call_sett_service(user_query: str, phone_number: str, conversation_id: Optional[str] = None, debug: bool = False, include_analysis: Optional[bool] = None, include_chart: Optional[bool] = None, is_monitor: bool = False, params: Optional[dict] = None) -> dict:
    start_time = time.time()
    
    # 如果是监控请求，添加特殊标识到查询中，确保每次都是真实调用
    if is_monitor:
        monitor_tag = f"[MONITOR_{int(time.time())}]"
        user_query = f"{monitor_tag} {user_query}"
        logging.info(f"[步骤2-轧差服务调用] 监控模式调用轧差服务，已添加监控标识")
    
    logging.info(f"[步骤2-轧差服务调用] 开始调用轧差数据服务")
    # 如果传入了conversation_id，则使用它；否则创建一个新的本地对话ID
    local_conversation_id = conversation_id if conversation_id else chat_history_manager.create_new_conversation()
    logging.info(f"[对话管理] 使用对话ID: {local_conversation_id}")
    
    # 获取对话历史
    history = chat_history_manager.get_history(local_conversation_id)
    logging.info(f"[对话管理] 历史消息数量: {len(history)}")
    if history:
        logging.info(f"[对话管理] 最近一条历史消息: {history[-1]['content'][:50]}...")
    
    # 检查用户查询是否为跨月记录确认响应
    user_response = user_query.strip().lower()
    if user_response in ['是', 'yes', 'y', '确认', 'include', '否', 'no', 'n', '不包含', 'exclude']:
        # 检查对话历史中是否有待确认的跨月记录信息
        confirmation_info = None
        for msg in reversed(history):
            if msg.get('role') == 'system':
                try:
                    content = json.loads(msg.get('content', '{}'))
                    if content.get('type') == 'cross_month_confirmation':
                        confirmation_info = content
                        break
                except (json.JSONDecodeError, TypeError):
                    continue
        
        if confirmation_info:
            # 如果是跨月确认响应，直接调用handle_cross_month_confirmation函数处理
            logging.info(f"[跨月记录确认] 检测到跨月确认响应，直接处理: {user_response}")
            return await handle_cross_month_confirmation(local_conversation_id, user_query, phone_number)
    
    # 检查是否为用户选择单位的响应（处理模糊查询后的用户选择）
    is_user_selection = False
    selected_unit_info = None
    
    # 检查用户查询是否为数字选择（1-5）
    if user_query.strip().isdigit() and 1 <= int(user_query.strip()) <= 5:
        # 检查历史中是否有模糊查询的响应
        for msg in reversed(history):
            if msg.get("role") == "assistant" and "相似的单位" in msg.get("content", ""):
                # 当用户输入数字时，直接执行用户选择逻辑，不进行重复匹配检查
                is_user_selection = True
                selection_index = int(user_query.strip()) - 1
                logging.info(f"[用户选择] 检测到用户选择第{user_query.strip()}个单位，直接执行用户选择逻辑")
                
                # 从历史中提取相似单位列表
                import re
                content = msg.get("content", "")
                
                # 使用大模型理解用户选择的序号对应的单位
                logging.info(f"[用户选择] 使用大模型解析用户选择第{selection_index + 1}个单位")
                
                try:
                    from utils import get_user_available_units
                    available_units = await get_user_available_units(phone_number, return_full_info=True)
                    
                    # 调用大模型函数解析用户选择的序号对应的单位
                    selected_unit_info = await _llm_understand_selection(content, selection_index, available_units)
                    
                    if selected_unit_info:
                        unit_full_name = selected_unit_info.get("unitFullName", "未知单位")
                        unit_id = selected_unit_info.get("unitId")
                        logging.info(f"[用户选择] 用户选择单位匹配成功: {unit_full_name} (ID: {unit_id})")
                        logging.info(f"[单位匹配完成] 用户选择单位匹配完成: {unit_full_name}")
                    else:
                        logging.warning(f"[用户选择] 大模型未能识别索引为{selection_index}的单位")
                        
                except Exception as e:
                    logging.error(f"[用户选择] 大模型处理用户选择失败: {str(e)}")
                
                break
    
    # 参数处理优先级：用户选择单位 > 外部传入参数 > 自动参数转换
    if is_user_selection and selected_unit_info:
        # 用户选择了单位，优先使用用户选择的信息
        logging.info(f"[参数转换] 处理用户选择的单位: {selected_unit_info.get('unitFullName', '未知单位')}")
        
        # 构建基础参数
        params = {
            "unitId": selected_unit_info.get("unitId"),
            "phoneNo": phone_number
        }
        
        # 添加时间参数（使用默认时间范围或从历史中提取）
        try:
            from utils import extract_time_params_from_history
            time_params = await extract_time_params_from_history(history)
            
            # 检查时间参数的置信度，只有在置信度较高时才使用
            confidence = time_params.get("confidence", 0.0)
            if time_params.get("startDate") and time_params.get("endDate") and confidence > 0.7:
                params["startDate"] = time_params["startDate"].replace("-", "")
                params["endDate"] = time_params["endDate"].replace("-", "")
                logging.info(f"[参数转换] 从历史中提取时间参数（置信度{confidence:.2f}）: {params['startDate']} 至 {params['endDate']}")
            else:
                # 使用智能默认时间范围
                from datetime import datetime, timedelta
                today = datetime.now()
                
                # 检查当前用户查询是否包含时间关键词
                current_user_query = user_query if user_query else ""
                time_keywords = ['今天', '昨天', '本周', '上周', '本月', '上月', '今年', '去年', 
                               '年', '月', '日', '号', '周', '季度', '上半年', '下半年']
                has_time_keywords = any(keyword in current_user_query for keyword in time_keywords)
                
                if has_time_keywords:
                    # 如果用户查询包含时间关键词，使用更短的时间范围（最近7天）
                    end_date = today.strftime("%Y%m%d")
                    start_date = (today - timedelta(days=7)).strftime("%Y%m%d")
                    logging.info(f"[参数转换] 用户查询包含时间关键词，使用最近7天时间范围: {start_date} 至 {end_date}")
                else:
                    # 默认使用最近3个月时间范围
                    end_date = today.strftime("%Y%m%d")
                    start_date = (today - timedelta(days=90)).strftime("%Y%m%d")
                    logging.info(f"[参数转换] 使用默认时间参数（最近3个月）: {start_date} 至 {end_date}")
                
                params["startDate"] = start_date
                params["endDate"] = end_date
        except Exception as e:
            logging.error(f"[参数转换] 提取时间参数失败: {str(e)}")
            # 使用默认时间范围（最近3个月）
            from datetime import datetime, timedelta
            today = datetime.now()
            end_date = today.strftime("%Y%m%d")
            start_date = (today - timedelta(days=90)).strftime("%Y%m%d")
            params["startDate"] = start_date
            params["endDate"] = end_date
            logging.info(f"[参数转换] 异常处理，使用默认时间参数: {start_date} 至 {end_date}")
        
        validated_params = UnitDateParams(**params).dict()
        logging.info(f"[参数转换] 用户选择单位后的完整参数: {validated_params}")
    elif params is not None:
        # 使用外部传入的参数（但用户未选择单位时）
        logging.info(f"[参数转换] 使用外部传入的轧差查询参数: {params}")
        # 确保params中包含手机号
        if 'phoneNo' not in params and phone_number:
            params['phoneNo'] = phone_number
        validated_params = UnitDateParams(**params).dict()
        # 用户选择了单位，构建完整参数
        logging.info(f"[参数转换] 处理用户选择的单位: {selected_unit_info.get('unitFullName', '未知单位')}")
        
        # 构建基础参数
        params = {
            "unitId": selected_unit_info.get("unitId"),
            "phoneNo": phone_number
        }
        
        # 添加时间参数（使用默认时间范围或从历史中提取）
        try:
            from utils import extract_time_params_from_history
            time_params = await extract_time_params_from_history(history)
            
            # 检查时间参数的置信度，只有在置信度较高时才使用
            confidence = time_params.get("confidence", 0.0)
            if time_params.get("startDate") and time_params.get("endDate") and confidence > 0.7:
                params["startDate"] = time_params["startDate"].replace("-", "")
                params["endDate"] = time_params["endDate"].replace("-", "")
                logging.info(f"[参数转换] 从历史中提取时间参数（置信度{confidence:.2f}）: {params['startDate']} 至 {params['endDate']}")
            else:
                # 使用智能默认时间范围
                from datetime import datetime, timedelta
                today = datetime.now()
                
                # 检查当前用户查询是否包含时间关键词
                current_user_query = user_query if user_query else ""
                time_keywords = ['今天', '昨天', '本周', '上周', '本月', '上月', '今年', '去年', 
                               '年', '月', '日', '号', '周', '季度', '上半年', '下半年']
                has_time_keywords = any(keyword in current_user_query for keyword in time_keywords)
                
                if has_time_keywords:
                    # 如果用户查询包含时间关键词，使用更短的时间范围（最近7天）
                    end_date = today.strftime("%Y%m%d")
                    start_date = (today - timedelta(days=7)).strftime("%Y%m%d")
                    logging.info(f"[参数转换] 用户查询包含时间关键词，使用最近7天时间范围: {start_date} 至 {end_date}")
                else:
                    # 默认使用最近3个月时间范围
                    end_date = today.strftime("%Y%m%d")
                    start_date = (today - timedelta(days=90)).strftime("%Y%m%d")
                    logging.info(f"[参数转换] 使用默认时间参数（最近3个月）: {start_date} 至 {end_date}")
                
                params["startDate"] = start_date
                params["endDate"] = end_date
        except Exception as e:
            logging.error(f"[参数转换] 提取时间参数失败: {str(e)}")
            # 使用默认时间范围（最近3个月）
            from datetime import datetime, timedelta
            today = datetime.now()
            end_date = today.strftime("%Y%m%d")
            start_date = (today - timedelta(days=90)).strftime("%Y%m%d")
            params["startDate"] = start_date
            params["endDate"] = end_date
            logging.info(f"[参数转换] 异常处理，使用默认时间参数: {start_date} 至 {end_date}")
        
        validated_params = UnitDateParams(**params).dict()
        logging.info(f"[参数转换] 用户选择单位后的完整参数: {validated_params}")
    else:
        params = await convert_params(user_query, "sett", phone_number, history, is_user_selection, selected_unit_info)  # 传递历史
        logging.info(f"[参数转换] 轧差查询参数: {params}")
        
        # 检查是否为模糊关键词处理结果
        if isinstance(params, dict) and params.get('is_ambiguous_keyword'):
            # 如果是模糊关键词，直接返回反问消息
            logging.info(f"[参数转换] 检测到模糊关键词，返回反问消息")
            ambiguous_response = params.get('ambiguous_response', {})
            
            # 保存对话记录到本地对话ID中
            chat_history_manager.add_message(local_conversation_id, "user", user_query)
            chat_history_manager.add_message(local_conversation_id, "assistant", ambiguous_response.get('response_message', ''))
            
            # 构建与普通查询结果一致的返回格式
            result = {
                "user_query": user_query,
                "summary": ambiguous_response.get('response_message', ''),
                "records": [],
                "download_links": [],
                "extend_question": ""
            }
            
            return {
                "answer": ambiguous_response.get('response_message', ''),
                "conversation_id": local_conversation_id,
                "result": result
            }
        
        validated_params = UnitDateParams(**params).dict()
    
    # 确保validated_params中包含手机号
    if 'phoneNo' not in validated_params and phone_number:
        validated_params['phoneNo'] = phone_number
    
    data = await service.call_api(Config.SETT_API_PATH, validated_params)
    
    # 确保data是字典类型
    if not isinstance(data, dict):
        logging.error(f"[API调用] 轧差 API返回类型错误，期望字典但得到: {type(data)}")
        raise HTTPException(status_code=500, detail="API返回数据格式错误")
    
    logging.info(f"[API调用] 轧差数据获取成功: {len(data.get('settList', []))}条记录")
    
    result = await process_sett_data(data, debug, user_query, validated_params, local_conversation_id, include_analysis, include_chart)
    
    # 检查是否需要用户确认跨月记录
    # 检查summary中是否包含跨月记录信息
    summary = result.get("summary", "")
    if "跨月记录" in summary and "请回复'是'或'否'" in summary:
        # 从summary中提取跨月记录信息
        import re
        
        # 提取跨月记录数量
        cross_month_count_match = re.search(r'发现(\d+)条跨月记录', summary)
        cross_month_count = int(cross_month_count_match.group(1)) if cross_month_count_match else 0
        
        # 提取跨月记录详细信息
        cross_month_records = []
        # 从result中获取已经处理好的跨月记录信息
        if 'cross_month_records' in result:
            cross_month_records = result['cross_month_records']
        else:
            # 如果result中没有，尝试从原始数据中获取跨月记录信息
            start_date = validated_params.get('startDate', '')
            end_date = validated_params.get('endDate', '')
            
            # 使用process_sett_data中相同的跨月记录筛选逻辑
            if 'data' in locals() and isinstance(data, dict) and 'settList' in data:
                extended_start_date = result.get('debug_info', {}).get('generated_params', {}).get('startDate', start_date)
                extended_end_date = result.get('debug_info', {}).get('generated_params', {}).get('endDate', end_date)
                
                for item in data['settList']:
                    item_start = item.get('startDate', '')
                    item_end = item.get('endDate', '')
                    
                    # 检查是否是跨月记录（使用与process_sett_data相同的逻辑）
                    try:
                        start_month = datetime.strptime(item_start, "%Y%m%d").month
                        end_month = datetime.strptime(item_end, "%Y%m%d").month
                        is_cross_month = start_month != end_month
                    except:
                        is_cross_month = False
                    
                    if is_cross_month:
                        # 检查是否有交集
                        has_intersection = False
                        if item_start and item_end:
                            has_intersection = (
                                (item_start <= end_date and item_end >= start_date)
                            )
                        
                        if has_intersection:
                            # 添加单位名称
                            unit_name = result.get('unit_name', '未知')
                            item_copy = item.copy()
                            item_copy['unit_name'] = unit_name
                            cross_month_records.append(item_copy)
        
        # 构建确认消息
        confirmation_msg = f"查询到{cross_month_count}条跨月记录，这些轧差表的日期范围跨越了您查询的时间范围。\n\n"
        confirmation_msg += "跨月记录列表：\n"
        
        for i, record in enumerate(cross_month_records, 1):
            # 获取单位名称，优先使用unit_name字段，如果没有则尝试从其他字段获取
            unit_name = record.get('unit_name')
            if not unit_name:
                unit_name = record.get('unitName')  # 尝试不同的字段名
            if not unit_name and 'companyId' in record:
                unit_name = f"单位ID: {record['companyId']}"
            if not unit_name:
                unit_name = "未知单位"
            
            # 构建日期范围显示
            start_date = record.get('startDate', '未知')
            end_date = record.get('endDate', '未知')
            date_range = f"{start_date}至{end_date}"
            
            confirmation_msg += f"{i}. {unit_name} - {date_range}\n"
        
        confirmation_msg += "\n请问您是否需要包含这些跨月记录？请回复'是'或'否'。"
        
        # 保存原始结果、跨月记录信息和查询参数到对话历史中，以便后续处理
        chat_history_manager.add_message(local_conversation_id, "system", json.dumps({
            "type": "cross_month_confirmation",
            "original_result": result,
            "cross_month_records": cross_month_records,
            "query_params": validated_params  # 保存查询参数
        }))
        
        # 返回需要确认的消息
        confirmation_result = {
            "summary": confirmation_msg
        }
        
        # 保存对话记录到本地对话ID中
        chat_history_manager.add_message(local_conversation_id, "user", user_query)
        chat_history_manager.add_message(local_conversation_id, "assistant", confirmation_msg)
        
        # 创建不包含cross_month_records字段的result副本
        clean_result = result.copy()
        if "cross_month_records" in clean_result:
            del clean_result["cross_month_records"]
        
        return {
            "answer": confirmation_msg,
            "conversation_id": local_conversation_id,
            "result": clean_result
        }
    
    # 保存对话记录到本地对话ID中
    chat_history_manager.add_message(local_conversation_id, "user", user_query)
    chat_history_manager.add_message(local_conversation_id, "assistant", result.get("summary", ""))
    
    end_time = time.time()
    logging.info(f"[步骤2-轧差服务调用] 调用轧差数据服务耗时: {end_time - start_time:.2f}秒")
    return {
        "answer": result.get("summary", ""),
        "conversation_id": local_conversation_id,
        "result": result
    }

# 处理用户对跨月记录确认响应的函数
async def handle_cross_month_confirmation(conversation_id: str, user_response: str, phone_number: str) -> dict:
    """
    处理用户对跨月记录的确认响应
    
    Args:
        conversation_id: 对话ID
        user_response: 用户响应（'是'或'否'）
        phone_number: 用户手机号
    
    Returns:
        dict: 处理结果
    """
    logging.info(f"[跨月记录确认] 开始处理用户确认响应，对话ID: {conversation_id}, 响应: {user_response}")
    
    # 获取对话历史中的确认信息
    history = chat_history_manager.get_history(conversation_id)
    confirmation_info = None
    
    # 查找最近的跨月确认信息
    for msg in reversed(history):
        if msg.get('role') == 'system':
            try:
                content = json.loads(msg.get('content', '{}'))
                if content.get('type') == 'cross_month_confirmation':
                    confirmation_info = content
                    break
            except (json.JSONDecodeError, TypeError):
                continue
    
    if not confirmation_info:
        raise HTTPException(status_code=400, detail="未找到待确认的跨月记录信息")
    
    original_result = confirmation_info.get('original_result', {})
    cross_month_records = confirmation_info.get('cross_month_records', [])
    query_params = confirmation_info.get('query_params', {})  # 从confirmation_info中获取查询参数
    
    # 标准化用户响应
    user_response = user_response.strip().lower()
    
    if user_response in ['是', 'yes', 'y', '确认', 'include']:
        # 用户确认包含跨月记录
        logging.info(f"[跨月记录确认] 用户确认包含{len(cross_month_records)}条跨月记录")
        
        # 获取原始记录
        original_records = original_result.get('records', [])
        original_download_links = original_result.get('download_links', [])
        
        # 重新调用API获取完整的跨月记录数据
        try:
            # 从confirmation_info中获取查询参数
            original_params = query_params
            
            # 构建包含跨月记录的查询参数
            cross_month_params = original_params.copy()
            # 扩展查询时间范围以包含所有跨月记录
            if cross_month_records:
                # 获取所有跨月记录的时间范围
                all_start_dates = [record.get('startDate') for record in cross_month_records if record.get('startDate')]
                all_end_dates = [record.get('endDate') for record in cross_month_records if record.get('endDate')]
                
                if all_start_dates and all_end_dates:
                    min_start_date = min(all_start_dates)
                    max_end_date = max(all_end_dates)
                    cross_month_params['startDate'] = min_start_date
                    cross_month_params['endDate'] = max_end_date
                    logging.info(f"[跨月记录确认] 扩展查询时间范围: {min_start_date}至{max_end_date}")
            
            # 重新调用API获取完整数据
            cross_month_result = await service.call_api(Config.SETT_API_PATH, cross_month_params)
            
            if cross_month_result and isinstance(cross_month_result, dict) and cross_month_result.get('records') is not None:
                # 使用API返回的完整记录数据
                all_records = cross_month_result.get('records', [])
                all_download_links = cross_month_result.get('download_links', [])
                
                # 更新摘要信息
                cross_month_result['summary'] = f"### 查询成功，共找到{len(all_records)}条轧差表记录（包含{len(cross_month_records)}条跨月记录）"
                
                # 添加跨月记录相关字段
                cross_month_result["include_cross_month"] = True
                cross_month_result["cross_month_count"] = len(cross_month_records)
                
                # 保存确认结果到对话历史
                chat_history_manager.add_message(conversation_id, "user", user_response)
                chat_history_manager.add_message(conversation_id, "assistant", cross_month_result['summary'])
                
                return {
                    "answer": cross_month_result['summary'],
                    "conversation_id": conversation_id,
                    "result": cross_month_result
                }
            else:
                logging.warning("[跨月记录确认] 重新查询API返回空结果，使用本地处理方式")
                
        except Exception as e:
            logging.error(f"[跨月记录确认] 重新查询API失败: {str(e)}，使用本地处理方式")
        
        # 如果重新查询失败，使用本地处理方式
        # 确保临时目录存在
        temp_dir = Config.TEMP_DOWNLOAD_PATH
        os.makedirs(temp_dir, exist_ok=True)
        
        # 处理跨月记录，生成记录内容和下载链接
        cross_month_record_contents = []
        cross_month_download_links = []
        
        for idx, sett in enumerate(cross_month_records, 1):
            # 为每条记录生成下载链接
            file_id = str(uuid.uuid4())
            tb_no = sett.get('tbNo', '未知')
            file_name = f"{tb_no}.xls"
            download_url = f"{Config.API_BASE_URL}/download/{file_id}?filename={file_name}"

            # 预生成文件（与正常轧差表相同的处理方式）
            try:
                # 调用下载接口
                logger.info(f"开始预生成跨月记录文件: {file_name}")
                download_params = {
                    "fileId": sett.get("fileId"),
                    "unitId": sett.get("unitId"),
                    "tbNo": tb_no
                }
                
                if not all(download_params.values()):
                    logger.warning(f"跨月记录缺少必要参数，跳过文件预生成: {tb_no}")
                else:
                    # 调用下载API
                    response = await service.call_api(Config.SETT_FILE_DOWN_API_PATH, download_params, stream=True)
                    
                    # 检查响应类型并进行类型断言
                    if not hasattr(response, 'headers'):
                        logger.error(f"下载API返回类型错误，期望ClientResponse但得到: {type(response)}")
                    else:
                        # 使用类型断言告诉类型检查器response的实际类型
                        response = cast(aiohttp.ClientResponse, response)
                        
                        try:
                            # 添加类型检查，确保response是ClientResponse对象
                            if hasattr(response, 'headers') and response.headers.get("Content-Type") == "application/octet-stream":
                                # 保存文件到临时目录
                                file_path = os.path.join(temp_dir, f"{file_id}_{file_name}")
                                
                                # 异步保存文件内容（使用流式处理，避免大文件导致连接关闭）
                                if hasattr(response, 'content'):
                                    async with aiofiles.open(file_path, 'wb') as f:
                                        # 分块读取和写入数据，避免一次性读取大文件导致连接关闭
                                        chunk_size = 65536  # 64KB
                                        while True:
                                            try:
                                                chunk = await response.content.read(chunk_size)
                                                if not chunk:
                                                    break
                                                await f.write(chunk)
                                            except Exception as e:
                                                logger.error(f"读取响应数据时发生错误: {str(e)}")
                                                break
                                
                                # 异步检查文件是否保存成功
                                if os.path.exists(file_path) and os.path.getsize(file_path) > 0:
                                    logger.info(f"跨月记录文件预生成成功: {file_path}")
                                else:
                                    logger.error(f"跨月记录文件预生成失败: {file_path}")
                            else:
                                # 处理非application/octet-stream类型的响应
                                content_type = response.headers.get("Content-Type", "unknown")
                                logger.warning(f"跨月记录下载API返回非预期的Content-Type: {content_type}")
                        finally:
                            # 确保关闭响应
                            if hasattr(response, 'closed') and hasattr(response, 'close') and not response.closed:
                                response.close()
            except Exception as e:
                logger.exception(f"跨月记录文件预生成异常: {str(e)}")
            
            # 构建记录内容
            record_content = []
            record_content.append(f"#### 第{len(original_records)+idx}条轧差表记录(跨月)")
            record_content.append(f"| 序号 | {len(original_records)+idx} |")
            record_content.append("|------|-----|")
            
            # 获取单位名称，优先使用unit_name字段，如果没有则尝试从其他字段获取
            unit_name = sett.get('unit_name')
            if not unit_name:
                unit_name = sett.get('unitName')  # 尝试不同的字段名
            if not unit_name and 'companyId' in sett:
                unit_name = f"单位ID: {sett['companyId']}"
            if not unit_name:
                unit_name = "未知单位"
            
            record_content.append(f"| 单位名称 | {unit_name} |")
            record_content.append(f"| 统一结算单位号 | {sett.get('companyId', '未知')} |")
            record_content.append(f"| 日期范围 | {sett.get('startDate', '未知')}至{sett.get('endDate', '未知')} |")
            record_content.append(f"| 消费笔数(笔) | {sett.get('totalTxnNum', '0')} |")
            record_content.append(f"| 合计消费金额(元) | {int(sett.get('totalTxnAmt', '0'))/100} |")
            record_content.append(f"| 实付金额(元) | {abs(int(sett.get('totalPayAmt', '0')))/100} |")
            record_content.append(f"| 消费手续费(元) | {int(sett.get('txnFeeAmt', '0'))/100} |")
            
            cross_month_record_contents.append("\n".join(record_content))
            
            cross_month_download_links.append({
                "index": len(original_records)+idx,
                "tb_no": tb_no,
                "download_url": download_url,
                "file_name": file_name,
                "file_type": "xls"
            })
        
        # 合并原始记录和跨月记录
        all_records = original_records + cross_month_record_contents
        all_download_links = original_download_links + cross_month_download_links
        
        # 构建包含跨月记录的响应
        # 获取原始查询时间范围
        original_result = confirmation_info.get('original_result', {})
        original_summary = original_result.get('summary', '')
        
        # 从原始摘要中提取时间范围
        import re
        time_range_match = re.search(r'(\d{8}至\d{8})', original_summary)
        if time_range_match:
            time_range = time_range_match.group(1)
            result_lines = [f"### 查询成功，共找到{len(all_records)}条轧差表记录（{time_range}，包含{len(cross_month_records)}条跨月记录）"]
        else:
            result_lines = [f"### 查询成功，共找到{len(all_records)}条轧差表记录（包含{len(cross_month_records)}条跨月记录）"]
        
        # 构建最终响应，保持与原始查询相同的数据结构
        final_result = original_result.copy()  # 复制原始结果的所有字段
        
        # 更新需要修改的字段
        final_result["summary"] = result_lines[0]
        final_result["records"] = all_records
        final_result["download_links"] = all_download_links
        
        # 添加跨月记录相关字段，但不改变原有结构
        final_result["include_cross_month"] = True
        final_result["cross_month_count"] = len(cross_month_records)
        
        # 保存确认结果到对话历史
        chat_history_manager.add_message(conversation_id, "user", user_response)
        chat_history_manager.add_message(conversation_id, "assistant", result_lines[0])
        
        return {
            "answer": result_lines[0],
            "conversation_id": conversation_id,
            "result": final_result
        }
        
    elif user_response in ['否', 'no', 'n', '不包含', 'exclude']:
        # 用户拒绝包含跨月记录
        logging.info(f"[跨月记录确认] 用户拒绝包含跨月记录")
        
        # 返回原始结果（不包含跨月记录），保持原始数据结构
        answer = original_result.get('summary', '查询完成，未包含跨月记录')
        
        # 构建最终结果，保持与原始查询相同的数据结构
        final_result = original_result.copy()  # 复制原始结果的所有字段
        
        # 添加跨月记录相关字段，但不改变原有结构
        final_result["include_cross_month"] = False
        final_result["cross_month_count"] = 0
        
        # 保存确认结果到对话历史
        chat_history_manager.add_message(conversation_id, "user", user_response)
        chat_history_manager.add_message(conversation_id, "assistant", answer)
        
        return {
            "answer": answer,
            "conversation_id": conversation_id,
            "result": final_result
        }
    else:
        # 用户响应不明确
        raise HTTPException(status_code=400, detail="请回复'是'或'否'来确认是否包含跨月记录")


async def _llm_understand_selection(content: str, selection_index: int, available_units: List[Dict]) -> Optional[Dict]:
    """
    使用大模型理解用户选择的序号对应的单位
    
    Args:
        content: 历史对话内容
        selection_index: 用户选择的索引（0-based）
        available_units: 可用单位列表
        
    Returns:
        匹配的单位信息字典，如果未找到则返回None
    """
    try:
        # 构建提示词 - 与发票服务保持一致
        prompt = f"""请根据以下对话历史，理解用户选择的序号对应的单位信息。

对话历史：
{content}

用户选择了第 {selection_index + 1} 个选项。

可用的单位列表：
{json.dumps(available_units, ensure_ascii=False, indent=2)}

请从可用单位列表中找出用户选择的单位，返回对应的完整单位信息。
如果找不到匹配的单位，请返回null。

请直接返回JSON格式的单位信息，不要添加任何解释。"""

        # 调用大模型
        response = await LLMService.call_qwen_model(prompt, temperature=0.0, timeout=30)
        
        # 解析响应
        if response and response.strip():
            try:
                # 尝试解析JSON响应
                unit_info = json.loads(response.strip())
                if isinstance(unit_info, dict) and unit_info.get('unitId'):
                    return unit_info
            except json.JSONDecodeError:
                logging.warning(f"LLM返回的响应不是有效的JSON格式: {response}")
        
        return None
        
    except Exception as e:
        logging.error(f"大模型理解用户选择失败: {str(e)}")
        return None